/**
 * 
 */
package jmath.function.meta;

import java.util.*;

import org.springframework.util.Assert;

// import org.apache.commons.logging.*;
import cern.colt.matrix.DoubleMatrix1D;

public class Dot {
	// private Log log = LogFactory.getLog(Dot.class);

	private final Map<String, Double> paramValueMap;

	private final DoubleMatrix1D xData;

	private final DoubleMatrix1D yData;

	private final Double resultValue;
	
	public String toString(){
		return (resultValue!=null?resultValue+":":"")
		+(paramValueMap!=null?paramValueMap+":":"");
	}
	

	public boolean isInInterval(String parameter, Interval interval) {
		return interval.isInInterval(paramValueMap.get(parameter));
	}

	public double getDistance(Dot dot) {
		double distance = 0;
		for (String key : this.paramValueMap.keySet()) {
			double thisDotParameter = this.paramValueMap.get(key).doubleValue();
			double thatDotParameter = dot.getParamValueMap().get(key)
					.doubleValue();
			distance = distance + 2
					* Math.abs(thisDotParameter - thatDotParameter)
					/ Math.abs(thisDotParameter + thatDotParameter);
		}

		return distance;
	}

	public Map<String, Double> getParamValueMap() {
		return this.paramValueMap;
	}

	public DoubleMatrix1D getXData() {
		return xData;
	}

	public DoubleMatrix1D getYData() {
		return yData;
	}

	public Double getResultValue() {
		return resultValue;
	}
	
	public static class Builder{
		private Map<String, Double> paramValueMap;

		private DoubleMatrix1D xData;

		private DoubleMatrix1D yData;

		private Double resultValue;
		
		public Builder setParamValueMap(Map<String, Double> paramValueMap){
			this.paramValueMap=new HashMap<String, Double>(paramValueMap);
			return this;
		}
		
		public Builder setXData(DoubleMatrix1D xData){
			this.xData=xData;
			return this;
		}
		
		public Builder setYData(DoubleMatrix1D yData){
			this.yData=yData;
			return this;
		}
		
		public Builder setResultValue(Double resultValue){
			this.resultValue=resultValue;
			return this;
		}
		
		public Dot build(){
			return new Dot(this);
		}
	}
	
	private Dot(Builder builder) {
		this.paramValueMap=builder.paramValueMap;
		Assert.isTrue(builder.xData.size()==builder.yData.size());
		this.xData=builder.xData;
		this.yData=builder.yData;
		this.resultValue=builder.resultValue;
	}

}
